#ifndef __TCPCLIENT_HPP__
#define __TCPCLIENT_HPP__

#include "common.hpp"


class tcpclient
{
private:
    /* data */
    std::string serverIP;
    uint16_t serverPort;
    std::string localIP;
    uint16_t localPort;

    void *parent;                           // 指向上一层
    uv_loop_t *loop;
    uv_tcp_t clientHandle;                
    uv_connect_t connectReq;      
    struct sockaddr_in serverAddr;          
    struct sockaddr_in localAddr;

    uv_timer_t reconnectTimer;              // 重连句柄
    bool connectStatus;
    bool isReconnect;
    bool isClosed;
    int32_t repeatTime;

    // recv
    uv_buf_t uvRbuf;
    uv_mutex_t rMutex;
    uint8_t *rbuff;
    uint32_t rbuffIn;
    uint32_t rbuffOut;

    // send
    uv_timer_t sendTimer;
    int32_t repeatSendTime;
    uv_async_t sendAsync;
    uv_mutex_t sMutex;
    uint8_t *sbuff;
    uint32_t sbuffIn;
    uint32_t sbuffOut;
    uv_write_t write_reqs;

public:
    tcpclient(uv_loop_t *ploop, std::string server_ip, uint16_t server_port, std::string local_ip, uint16_t local_port);
    ~tcpclient();

    std::string tcGetIP();
    int32_t tcGetPort();
    int32_t tcSendData(uint8_t *sdata, int32_t sdata_len);
    int32_t tcRecvData(uint8_t *buff, int32_t buff_len);
    bool tcGetConnectStatus();

protected:
    static void sTCAfterConnect(uv_connect_t* handle, int status);
    static void sTCAllocBufferForRecv(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf);
    static void sTCAfterRecv(uv_stream_t* client, ssize_t nread, const uv_buf_t* buf);

    static void sTCReconnectTimer(uv_timer_t* handle);

    static void sTCAfterClientClose(uv_handle_t* handle);


    static void sTCSendTimer(uv_timer_t* handle);
    static void sTCSendAsync(uv_async_t *handle);
    static void sTCAfterSend(uv_write_t* req, int status);

private:
    void TCStartReconnect(void);
    void TCStopReconnect(void);

    void TCStartSend(void);
    void TCStopSend(void);
};



#endif
